home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 21 / Cream of the Crop 21 (Terry Blount) (October 1996).iso / doom / qplus10.zip / DOORS.QC < prev    next >
Text File  |  1996-08-18  |  17KB  |  792 lines

  1.  
  2. float DOOR_START_OPEN = 1;
  3. float DOOR_DONT_LINK = 4;
  4. float DOOR_GOLD_KEY = 8;
  5. float DOOR_SILVER_KEY = 16;
  6. float DOOR_TOGGLE = 32;
  7.  
  8. /*
  9.  
  10. Doors are similar to buttons, but can spawn a fat trigger field around them
  11. to open without a touch, and they link together to form simultanious
  12. double/quad doors.
  13.  
  14. Door.owner is the master door.  If there is only one door, it points to itself.
  15. If multiple doors, all will point to a single one.
  16.  
  17. Door.enemy chains from the master door through all doors linked in the chain.
  18.  
  19. */
  20.  
  21. /*
  22. =============================================================================
  23.  
  24. THINK FUNCTIONS
  25.  
  26. =============================================================================
  27. */
  28.  
  29. void() door_go_down;
  30. void() door_go_up;
  31.  
  32. void() door_blocked =
  33. {
  34.     T_Damage (other, self, self, self.dmg);
  35.     
  36. // if a door has a negative wait, it would never come back if blocked,
  37. // so let it just squash the object to death real fast
  38.     if (self.wait >= 0)
  39.     {
  40.         if (self.state == STATE_DOWN)
  41.             door_go_up ();
  42.         else
  43.             door_go_down ();
  44.     }
  45. };
  46.  
  47.  
  48. void() door_hit_top =
  49. {
  50.     sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
  51.     self.state = STATE_TOP;
  52.     if (self.spawnflags & DOOR_TOGGLE)
  53.         return;        // don't come down automatically
  54.     self.think = door_go_down;
  55.     self.nextthink = self.ltime + self.wait;
  56. };
  57.  
  58. void() door_hit_bottom =
  59. {
  60.     sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
  61.     self.state = STATE_BOTTOM;
  62. };
  63.  
  64. void() door_go_down =
  65. {
  66.     sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
  67.     if (self.max_health)
  68.     {
  69.         self.takedamage = DAMAGE_YES;
  70.         self.health = self.max_health;
  71.         self.flags = FL_OBJECT;            //ws
  72.     }
  73.     
  74.     self.state = STATE_DOWN;
  75.     SUB_CalcMove (self.pos1, self.speed, door_hit_bottom);
  76. };
  77.  
  78. void() door_go_up =
  79. {
  80.     if (self.state == STATE_UP)
  81.         return;        // allready going up
  82.  
  83.     if (self.state == STATE_TOP)
  84.     {    // reset top wait time
  85.         self.nextthink = self.ltime + self.wait;
  86.         return;
  87.     }
  88.     
  89.     sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
  90.     self.state = STATE_UP;
  91.     SUB_CalcMove (self.pos2, self.speed, door_hit_top);
  92.  
  93.     SUB_UseTargets();
  94. };
  95.  
  96.  
  97. /*
  98. =============================================================================
  99.  
  100. ACTIVATION FUNCTIONS
  101.  
  102. =============================================================================
  103. */
  104.  
  105. void() door_fire =
  106. {
  107.     local entity     oself;
  108.     local entity    starte;
  109.  
  110.     if (self.owner != self)
  111.         objerror ("door_fire: self.owner != self");
  112.  
  113. // play use key sound
  114.  
  115.     if (self.items)
  116.         sound (self, CHAN_VOICE, self.noise4, 1, ATTN_NORM);
  117.  
  118.     self.message = string_null;        // no more message
  119.     oself = self;
  120.  
  121.     if (self.spawnflags & DOOR_TOGGLE)
  122.     {
  123.         if (self.state == STATE_UP || self.state == STATE_TOP)
  124.         {
  125.             starte = self;
  126.             do
  127.             {
  128.                 door_go_down ();
  129.                 self = self.enemy;
  130.             } while ( (self != starte) && (self != world) );
  131.             self = oself;
  132.             return;
  133.         }
  134.     }
  135.     
  136. // trigger all paired doors
  137.     starte = self;
  138.     do
  139.     {
  140.         door_go_up ();
  141.         self = self.enemy;
  142.     } while ( (self != starte) && (self != world) );
  143.     self = oself;
  144. };
  145.  
  146.  
  147. void() door_use =
  148. {
  149.     local entity oself;
  150.  
  151.     self.message = "";            // door message are for touch only
  152.     self.owner.message = "";    
  153.     self.enemy.message = "";
  154.     oself = self;
  155.     self = self.owner;
  156.     door_fire ();
  157.     self = oself;
  158. };
  159.  
  160.  
  161. void() door_trigger_touch =
  162. {
  163.     if (other.health <= 0)
  164.         return;
  165.     if (time < self.attack_finished)
  166.         return;
  167.     if (other.impulse != 14)        //ws
  168.         return;            //ws
  169.     useget = 0;            //ws
  170.  
  171.     self.attack_finished = time + 1;
  172.  
  173.     activator = other;
  174.  
  175.     self = self.owner;
  176.     door_use ();
  177. };
  178.  
  179.  
  180. void() door_killed =
  181. {
  182.     local entity oself;
  183.     
  184.     oself = self;
  185.     self = self.owner;
  186.     self.health = self.max_health;
  187.     self.takedamage = DAMAGE_NO;    // wil be reset upon return
  188.     door_use ();
  189.     self = oself;
  190. };
  191.  
  192.  
  193. /*
  194. ================
  195. door_touch
  196.  
  197. Prints messages and opens key doors
  198. ================
  199. */
  200. void() door_touch =
  201. {
  202.     if (other.classname != "player")
  203.         return;
  204.     if (self.owner.attack_finished > time)
  205.         return;
  206.     if (other.impulse != 14)        //ws
  207.         return;            //ws
  208.     useget = 0;            //ws
  209.  
  210.  
  211.     self.owner.attack_finished = time + 2;
  212.  
  213.     if (self.owner.message != "")
  214.     {
  215.         centerprint (other, self.owner.message);
  216.         sound (other, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);
  217.     }
  218.     
  219. // key door stuff
  220.     if (!self.items)
  221.         return;
  222.  
  223. // FIXME: blink key on player's status bar
  224.     if ( (self.items & other.items) != self.items )
  225.     {
  226.         if (self.owner.items == IT_KEY1)
  227.         {
  228.             if (world.worldtype == 2)
  229.             {
  230.                 centerprint (other, "You need the silver keycard");
  231.                 sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
  232.             }
  233.             else if (world.worldtype == 1)
  234.             {
  235.                 centerprint (other, "You need the silver runekey");
  236.                 sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
  237.             }
  238.             else if (world.worldtype == 0)
  239.             {
  240.                 centerprint (other, "You need the silver key");
  241.                 sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
  242.             }
  243.         }
  244.         else
  245.         {
  246.             if (world.worldtype == 2)
  247.             {
  248.                 centerprint (other, "You need the gold keycard");
  249.                 sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
  250.             }
  251.             else if (world.worldtype == 1)
  252.             {
  253.                 centerprint (other, "You need the gold runekey");
  254.                 sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);            
  255.             }
  256.             else if (world.worldtype == 0)
  257.             {
  258.                 centerprint (other, "You need the gold key");
  259.                 sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
  260.             }
  261.         }
  262.         return;
  263.     }
  264.  
  265.     other.items = other.items - self.items;
  266.     self.touch = SUB_Null;
  267.     if (self.enemy)
  268.         self.enemy.touch = SUB_Null;    // get paired door
  269.     door_use ();
  270. };
  271.  
  272. /*
  273. =============================================================================
  274.  
  275. SPAWNING FUNCTIONS
  276.  
  277. =============================================================================
  278. */
  279.  
  280.  
  281. entity(vector fmins, vector fmaxs) spawn_field =
  282. {
  283.     local entity    trigger;
  284.     local    vector    t1, t2;
  285.  
  286.     trigger = spawn();
  287.     trigger.movetype = MOVETYPE_NONE;
  288.     trigger.solid = SOLID_TRIGGER;
  289.     trigger.owner = self;
  290.     trigger.touch = door_trigger_touch;
  291.  
  292.     t1 = fmins;
  293.     t2 = fmaxs;
  294.     setsize (trigger, t1 - '60 60 8', t2 + '60 60 8');
  295.     return (trigger);
  296. };
  297.  
  298.  
  299. float (entity e1, entity e2) EntitiesTouching =
  300. {
  301.     if (e1.mins_x > e2.maxs_x)
  302.         return FALSE;
  303.     if (e1.mins_y > e2.maxs_y)
  304.         return FALSE;
  305.     if (e1.mins_z > e2.maxs_z)
  306.         return FALSE;
  307.     if (e1.maxs_x < e2.mins_x)
  308.         return FALSE;
  309.     if (e1.maxs_y < e2.mins_y)
  310.         return FALSE;
  311.     if (e1.maxs_z < e2.mins_z)
  312.         return FALSE;
  313.     return TRUE;
  314. };
  315.  
  316.  
  317. /*
  318. =============
  319. LinkDoors
  320.  
  321.  
  322. =============
  323. */
  324. void() LinkDoors =
  325. {
  326.     local entity    t, starte;
  327.     local vector    cmins, cmaxs;
  328.  
  329.     if (self.enemy)
  330.         return;        // already linked by another door
  331.     if (self.spawnflags & 4)
  332.     {
  333.         self.owner = self.enemy = self;
  334.         return;        // don't want to link this door
  335.     }
  336.  
  337.     cmins = self.mins;
  338.     cmaxs = self.maxs;
  339.     
  340.     starte = self;
  341.     t = self;
  342.     
  343.     do
  344.     {
  345.         self.owner = starte;            // master door
  346.  
  347.         if (self.health)
  348.             starte.health = self.health;
  349.         if (self.targetname)
  350.             starte.targetname = self.targetname;
  351.         if (self.message != "")
  352.             starte.message = self.message;
  353.  
  354.         t = find (t, classname, self.classname);    
  355.         if (!t)
  356.         {
  357.             self.enemy = starte;        // make the chain a loop
  358.  
  359.         // shootable, fired, or key doors just needed the owner/enemy links,
  360.         // they don't spawn a field
  361.     
  362.             self = self.owner;
  363.  
  364.             if (self.health)
  365.                 return;
  366.             if (self.targetname)
  367.                 return;
  368.             if (self.items)
  369.                 return;
  370.  
  371.             self.owner.trigger_field = spawn_field(cmins, cmaxs);
  372.  
  373.             return;
  374.         }
  375.  
  376.         if (EntitiesTouching(self,t))
  377.         {
  378.             if (t.enemy)
  379.                 objerror ("cross connected doors");
  380.             
  381.             self.enemy = t;
  382.             self = t;
  383.  
  384.             if (t.mins_x < cmins_x)
  385.                 cmins_x = t.mins_x;
  386.             if (t.mins_y < cmins_y)
  387.                 cmins_y = t.mins_y;
  388.             if (t.mins_z < cmins_z)
  389.                 cmins_z = t.mins_z;
  390.             if (t.maxs_x > cmaxs_x)
  391.                 cmaxs_x = t.maxs_x;
  392.             if (t.maxs_y > cmaxs_y)
  393.                 cmaxs_y = t.maxs_y;
  394.             if (t.maxs_z > cmaxs_z)
  395.                 cmaxs_z = t.maxs_z;
  396.         }
  397.     } while (1 );
  398.  
  399. };
  400.  
  401.  
  402. /*QUAKED func_door (0 .5 .8) ? START_OPEN x DOOR_DONT_LINK GOLD_KEY SILVER_KEY TOGGLE
  403. if two doors touch, they are assumed to be connected and operate as a unit.
  404.  
  405. TOGGLE causes the door to wait in both the start and end states for a trigger event.
  406.  
  407. START_OPEN causes the door to move to its destination when spawned, and operate in reverse.  It is used to temporarily or permanently close off an area when triggered (not usefull for touch or takedamage d